package com.kexio.file.service;

import java.io.InputStream;
import java.util.List;

import com.kexio.common.dto.PageRequest;
import com.kexio.common.dto.PageResponse;
import com.kexio.file.dto.FileChunk;
import com.kexio.file.dto.FileUploadRequest;
import com.kexio.file.dto.FileUploadResult;
import com.kexio.file.domain.FileInfo;

/**
 * 文件服务接口
 * 
 * @author kexio
 */
public interface FileService {

    /**
     * 上传文件
     *
     * @param request 上传请求
     * @param inputStream 文件流
     * @return 上传结果
     */
    FileUploadResult uploadFile(FileUploadRequest request, InputStream inputStream);

    /**
     * 检查文件是否可以秒传
     *
     * @param fileHash 文件哈希值
     * @param fileSize 文件大小
     * @return 可以秒传的文件信息，否则返回null
     */
    FileInfo checkInstantUpload(String fileHash, Long fileSize);

    /**
     * 执行文件秒传
     *
     * @param request 上传请求
     * @param existingFileId 已存在的文件ID
     * @return 秒传结果
     */
    FileUploadResult instantUpload(FileUploadRequest request, Long existingFileId);

    /**
     * 初始化分片上传
     *
     * @param request 上传请求
     * @return 上传ID
     */
    String initChunkUpload(FileUploadRequest request);

    /**
     * 上传文件分片
     *
     * @param uploadId 上传ID
     * @param chunk 分片数据
     * @return 分片ID
     */
    String uploadChunk(String uploadId, FileChunk chunk);

    /**
     * 合并文件分片
     *
     * @param uploadId 上传ID
     * @param chunkIds 分片ID列表
     * @param request 原始上传请求
     * @return 上传结果
     */
    FileUploadResult mergeChunks(String uploadId, List<String> chunkIds, FileUploadRequest request);

    /**
     * 取消分片上传
     *
     * @param uploadId 上传ID
     * @return 是否成功
     */
    boolean abortChunkUpload(String uploadId);

    /**
     * 下载文件
     *
     * @param fileId 文件ID
     * @param userId 用户ID（用于权限检查）
     * @return 文件流
     */
    InputStream downloadFile(Long fileId, Long userId);

    /**
     * 获取文件访问URL
     *
     * @param fileId 文件ID
     * @param userId 用户ID（用于权限检查）
     * @param expireSeconds 过期时间（秒）
     * @return 访问URL
     */
    String getFileAccessUrl(Long fileId, Long userId, int expireSeconds);

    /**
     * 删除文件
     *
     * @param fileId 文件ID
     * @param userId 用户ID（用于权限检查）
     * @return 是否成功
     */
    boolean deleteFile(Long fileId, Long userId);

    /**
     * 批量删除文件
     *
     * @param fileIds 文件ID列表
     * @param userId 用户ID（用于权限检查）
     * @return 删除成功的数量
     */
    int batchDeleteFiles(List<Long> fileIds, Long userId);

    /**
     * 根据ID查询文件信息
     *
     * @param fileId 文件ID
     * @return 文件信息
     */
    FileInfo getFileById(Long fileId);

    /**
     * 根据文件哈希查询文件信息
     *
     * @param fileHash 文件哈希
     * @return 文件信息
     */
    FileInfo getFileByHash(String fileHash);

    /**
     * 分页查询文件
     *
     * @param businessType 业务类型（可选）
     * @param businessId 业务ID（可选）
     * @param userId 用户ID（可选）
     * @param pageRequest 分页参数
     * @return 分页结果
     */
    PageResponse<FileInfo> queryFiles(String businessType, String businessId, Long userId, PageRequest pageRequest);

    /**
     * 复制文件
     *
     * @param sourceFileId 源文件ID
     * @param targetRequest 目标文件请求
     * @param userId 用户ID
     * @return 复制结果
     */
    FileUploadResult copyFile(Long sourceFileId, FileUploadRequest targetRequest, Long userId);

    /**
     * 检查用户是否有文件访问权限
     *
     * @param fileId 文件ID
     * @param userId 用户ID
     * @param permission 权限类型（read/write/delete）
     * @return 是否有权限
     */
    boolean checkFilePermission(Long fileId, Long userId, String permission);

    /**
     * 更新文件访问统计
     *
     * @param fileId 文件ID
     * @param userId 访问用户ID
     */
    void updateFileAccessStats(Long fileId, Long userId);

    /**
     * 生成文件预览URL
     *
     * @param fileId 文件ID
     * @param userId 用户ID
     * @return 预览URL
     */
    String generatePreviewUrl(Long fileId, Long userId);

    /**
     * 获取文件统计信息
     *
     * @param businessType 业务类型（可选）
     * @param userId 用户ID（可选）
     * @return 统计信息
     */
    FileStatistics getFileStatistics(String businessType, Long userId);

    /**
     * 文件统计信息
     */
    class FileStatistics {
        private Long totalFiles;
        private Long totalSize;
        private Long totalDownloads;
        
        public Long getTotalFiles() { return totalFiles; }
        public void setTotalFiles(Long totalFiles) { this.totalFiles = totalFiles; }
        
        public Long getTotalSize() { return totalSize; }
        public void setTotalSize(Long totalSize) { this.totalSize = totalSize; }
        
        public Long getTotalDownloads() { return totalDownloads; }
        public void setTotalDownloads(Long totalDownloads) { this.totalDownloads = totalDownloads; }
    }
}
